<?php
// +----------------------------------------------------------------------
// | yogurt
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Author: fengyi <1719847255.qq.com>
// +----------------------------------------------------------------------

namespace yogurt;

use yogurt\file\File;

class Console
{

    /**
     * 控制台初始化方法
     */
    public static function init()
    {
        if (!isset($_SERVER['argv'][0]) || !isset($_SERVER['argv'][1])) {
            exit('parameter error.');
        }

        // 运行内置服务器
        if ($_SERVER['argv'][1] == 'run') {
            self::runServer();
        }

        // 查看版本号
        if ($_SERVER['argv'][1] == 'version') {
            self::version();
        }

        // 生成模块文件
        if (strpos($_SERVER['argv'][1], 'build') !== false) {
            self::build();
        }

        // 生成类文件
        if (strpos($_SERVER['argv'][1], 'make') !== false) {
            self::make();
        }

        // 清除缓存文件
        if ($_SERVER['argv'][1] == 'clear') {
            self::clear();
        }
    }


    /**
     * 运行内置服务器
     */
    public static function runServer()
    {
        $http = $_SERVER['argv'][2] ?? '127.0.0.1:8000';
        echo 'running...' . PHP_EOL;
        echo 'Yogurt Development server is started On <http://' . $http . '/>' . PHP_EOL;
        echo 'You can exit with `CTRL-C`' . PHP_EOL;
        echo 'Document root is: ' . realpath(PUBLIC_PATH) . PHP_EOL;
        system('php -S ' . $http);
    }


    /**
     * 查看版本号
     */
    public static function version()
    {
        echo VERSION . PHP_EOL;
    }


    /**
     * 自动生成模块文件
     */
    public static function build()
    {
        if ($_SERVER['argv'][2] == '--module') {
            $modulePath = APP_PATH . $_SERVER['argv'][3] . DIRECTORY_SEPARATOR;
            $c = File::directory($modulePath . Config::get('app.controller_directory'));
            $v = File::directory($modulePath . Config::get('app.view_directory'));
            $m = File::directory($modulePath . Config::get('app.model_directory'));
            if ($c && $v && $m) {
                exit('module file generated successfully!' . PHP_EOL);
            }
        }
        exit('parameter error!');
    }


    /**
     * 自动生成类文件
     */
    public static function make()
    {
        if ($_SERVER['argv'][2] == '--controller') {

            if (self::createController()) {
                exit('controller file generated successfully!' . PHP_EOL);
            }
            exit('controller file creation failed!' . PHP_EOL);
        }

        if ($_SERVER['argv'][2] == '--model') {

            if (self::createModel()) {
                exit('model file generated successfully!' . PHP_EOL);
            }
            exit('model file creation failed!' . PHP_EOL);
        }

        if ($_SERVER['argv'][2] == '--validate') {

            if (self::createValidate()) {
                exit('validate file generated successfully!' . PHP_EOL);
            }
            exit('validate file creation failed!' . PHP_EOL);
        }

        if ($_SERVER['argv'][2] == '--middleware') {

            if (self::createMiddleware()) {
                exit('middleware file generated successfully!' . PHP_EOL);
            }
            exit('middleware file creation failed!' . PHP_EOL);
        }

        exit('parameter error!');
    }

    /**
     * 创建控制器类文件
     * @return bool
     * @throws \yogurt\Exception
     */
    protected static function createController(): bool
    {
        $controllers = explode('/', $_SERVER['argv'][3]);
        $controllerPath = APP_PATH . $controllers[0] . DIRECTORY_SEPARATOR . Config::get('app.controller_directory');
        if (!is_dir($controllerPath)) {
            mkdir($controllerPath);
        }
        $controllerFile = $controllerPath . DIRECTORY_SEPARATOR . ucfirst($controllers[1]) . PHP_SUFFIX;

        $data = '<?php' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'namespace app\\' . $controllers[0] . '\\' . Config::get('app.controller_directory') . ';' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'use yogurt\Controller;' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'class ' . ucfirst($controllers[1]) . ' extends Controller' . PHP_EOL;
        $data .= '{' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '}' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= '?>';

        if (file_put_contents($controllerFile, $data)) {
            return true;
        }
        return false;
    }

    /**
     * 创建模型类文件
     * @return bool
     * @throws \yogurt\Exception
     */
    protected static function createModel(): bool
    {
        $models = explode('/', $_SERVER['argv'][3]);
        $modelPath = APP_PATH . $models[0] . DIRECTORY_SEPARATOR . Config::get('app.model_directory');
        if (!is_dir($modelPath)) {
            mkdir($modelPath);
        }
        $modelFile = $modelPath . DIRECTORY_SEPARATOR . ucfirst($models[1]) . PHP_SUFFIX;

        $data = '<?php' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'namespace app\\' . $models[0] . '\\' . Config::get('app.model_directory') . ';' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'use yogurt\Model;' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'class ' . ucfirst($models[1]) . ' extends Model' . PHP_EOL;
        $data .= '{' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '}' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= '?>';

        if (file_put_contents($modelFile, $data)) {
            return true;
        }
        return false;
    }


    /**
     * 创建验证器类文件
     * @return bool
     */
    protected static function createValidate(): bool
    {
        $validates = explode('/', $_SERVER['argv'][3]);
        $validatePath = APP_PATH . $validates[0] . DIRECTORY_SEPARATOR . 'validate';
        if (!is_dir($validatePath)) {
            mkdir($validatePath);
        }
        $validateFile = $validatePath . DIRECTORY_SEPARATOR . ucfirst($validates[1]) . PHP_SUFFIX;

        $data = '<?php' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'namespace app\\' . $validates[0] . '\\' . 'validate' . ';' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'use yogurt\Validate;' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'class ' . ucfirst($validates[1]) . ' extends Validate' . PHP_EOL;
        $data .= '{' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '    protected $rule = [];' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= '    protected $message = [];' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '}' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= '?>';

        if (file_put_contents($validateFile, $data)) {
            return true;
        }
        return false;
    }


    /**
     * 创建中间件类文件
     * @return bool
     */
    protected static function createMiddleware(): bool
    {
        $middlewares = explode('/', $_SERVER['argv'][3]);
        if (count($middlewares) == 1) {
            $middlewarePath = APP_PATH . 'middleware';
            if (!is_dir($middlewarePath)) {
                mkdir($middlewarePath);
            }
            $middlewareFile = $middlewarePath . DIRECTORY_SEPARATOR . ucfirst($middlewares[0]) . PHP_SUFFIX;
            $namespace = 'namespace app\\' . $middlewares[0] . ';' . PHP_EOL;
            $classname = ucfirst($middlewares[0]);
        } else {
            $middlewarePath = APP_PATH . $middlewares[0] . DIRECTORY_SEPARATOR . 'middleware';
            if (!is_dir($middlewarePath)) {
                mkdir($middlewarePath);
            }
            $middlewareFile = $middlewarePath . DIRECTORY_SEPARATOR . ucfirst($middlewares[1]) . PHP_SUFFIX;
            $namespace = 'namespace app\\' . $middlewares[0] . '\\' . 'middleware' . ';' . PHP_EOL;
            $classname = ucfirst($middlewares[1]);
        }

        $data = '<?php' . PHP_EOL;
        $data .= PHP_EOL;

        $data .= $namespace;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'use Closure;' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= 'class ' . $classname . PHP_EOL;
        $data .= '{' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '    /**
     * 响应处理请求
     * @param $request
     * @param \Closure $next
     * @return mixed
     */';
        $data .= PHP_EOL;
        $data .= '    public function handle($request, Closure $next)' . PHP_EOL;
        $data .= '    {';

        $data .= PHP_EOL;
        $data .= PHP_EOL;

        $data .= '        $response = $next($request);';
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '        return $response;';

        $data .= PHP_EOL;
        $data .= PHP_EOL;

        $data .= '    }';
        $data .= PHP_EOL;
        $data .= PHP_EOL;
        $data .= '}' . PHP_EOL;
        $data .= PHP_EOL;
        $data .= '?>';

        if (file_put_contents($middlewareFile, $data)) {
            return true;
        }
        return false;
    }


    /**
     * 清除缓存文件
     */
    public static function clear()
    {
        if (File::rm(ROOT_PATH . 'runtime')) {
            echo 'cache file cleared successfully!' . PHP_EOL;
        } else {
            echo 'cache file cleanup failed!' . PHP_EOL;
        }
    }
}
